/**
 * 枚举工厂函数
 */
class EnumFactory {
  /**
   * 接收一个枚举对象和一个键解析函数作为参数;
   * 构造函数
   * @param {*} enumObj 枚举值，支持标准模式{key:{text,type},}，简单模式{key:text,}（会自动转换为标准模式）
   * @param {*} keyParseFunc key的转换函数，默认null，如果key为整数则传 parseInt
   */
  constructor(enumObj, keyParseFunc = null) {
    // 将枚举对象赋值给当前对象
    Object.assign(this, enumObj)

    // 定义一个keys属性，如果传入键解析函数，则使用键解析函数解析枚举对象的键，否则直接使用枚举对象的键
    Object.defineProperty(this, 'keys', {
      value: keyParseFunc
        ? Object.keys(enumObj).map((s) => keyParseFunc(s))
        : Object.keys(enumObj)
    })

    // 定义一个values属性，用于存储枚举对象的值
    let values = []
    // 获取枚举对象的值
    const Ovalues = Object.values(enumObj)
    // 如果枚举对象的第一个值是字符串，则将枚举对象的键和值组合成一个对象，并添加到values数组中
    if (typeof Ovalues[0] === 'string') {
      Ovalues.forEach((text, index) => {
        const obj = { key: this.keys[index], text }
        values.push(obj)
        this[this.keys[index]] = obj
      })
      // 否则，直接将枚举对象的值添加到values数组中
    } else {
      Ovalues.forEach((item, index) => {
        item.key = this.keys[index]
        values.push(item)
      })
    }

    // 定义一个values属性，用于存储枚举对象的值
    Object.defineProperty(this, 'values', {
      value: values
    })

    // 定义一个formatter属性，用于格式化枚举对象的值
    Object.defineProperty(this, 'formatter', {
      value: (r, c, value) => {
        // 如果枚举对象的值中存在与传入的值相等的键或文本，则返回对应的文本，否则返回'notfound'
        return (
          values.filter((v) => v.key == value || v.text == value)[0]?.text ||
          'notfound'
        )
      }
    })

    // 冻结当前对象，使其不可修改
    Object.freeze(this)
  }
}

export default EnumFactory
